﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;

using Noris.Schedule.Support;
using Noris.Schedule.Support.Services;

namespace Noris.Schedule.Planning.Services
{
	#region DEFAULT PALETTE GENERÁTOR - objekt typu IGraphElementPalette
	internal class PaletteGraphDefault : IGraphElementPalette
	{
		/// <summary>
		/// Vrátí prioritu tohoto nástroje pro daný graf
		/// </summary>
		/// <param name="graphKey"></param>
		/// <returns></returns>
		public float GetPriority(GraphElementPaletteKey graphKey)
		{
			// Každý, kdo vrátí hodnotu typicky 1, bude mít větší šanci než zdejší provider.
			// Zdejší provider je naprosto obecný.
			return 0.25F;
		}
		/// <summary>
		/// Vrátí pero
		/// </summary>
		/// <param name="args"></param>
		/// <returns></returns>
		public Pen GetPen(GraphElementPaletteArgs args)
		{
			return new Pen(Color.Black);
		}
		/// <summary>
		/// Vrátí štětec.
		/// Vygeneruje štětec pro aktuální potřebu.
		/// Pokud tatáž potřeba nastane opakovaně, nadřízený systém vrátí štětec ze své paměti.
		/// </summary>
		/// <param name="args"></param>
		/// <param name="rectangle"></param>
		/// <param name="repeatType"></param>
		/// <returns></returns>
		public Brush GetBrush(GraphElementPaletteArgs args, Rectangle area, out GraphicsPaletteBrushRepeatType repeatType)
		{
			switch (args.GraphMode)
			{
				case RowGraphMode.Gantt:
					return this._GetBrushGantt(args, area, out repeatType);
				case RowGraphMode.TaskCapacityLink:
					return this._GetBrushTaskCapacityLink(args, area, out repeatType);
			}
			repeatType = GraphicsPaletteBrushRepeatType.None;
			return new SolidBrush(Color.LightSkyBlue);
		}
		/// <summary>
		/// Vrátí Brush pro graf typu TaskCapacityLink
		/// </summary>
		/// <param name="args"></param>
		/// <param name="area"></param>
		/// <param name="repeatType"></param>
		/// <returns></returns>
		private Brush _GetBrushGantt(GraphElementPaletteArgs args, Rectangle area, out GraphicsPaletteBrushRepeatType repeatType)
		{
			repeatType = GraphicsPaletteBrushRepeatType.Horizontal;
			Color basicColor = args.ElementColor;   // Základní barva, střed objektu
			Color lightColor = basicColor;          // Světlejší barva, většinou bývá nahoře (kromě stavu _GraphElementGradientType.ActiveItemBack)
			Color darkColor = basicColor;           // Tmavší barva, většinou je dole
			Color mediumColor;
			Color edgeColor = basicColor;           // Přechodová barva, jen v ActiveItemBack gradientu

			LinearGradientBrush lgb = new LinearGradientBrush(area, Color.LightGray, Color.Gray, 90F);
			ColorBlend cbl;
			HatchBrush htb;

			switch (args.ElementState)
			{
				case GraphElementState.Dead:             // Neinteraktivní element:
					repeatType = GraphicsPaletteBrushRepeatType.None;
					lightColor = ComponentLibrary.ColorShift(basicColor, +64);
					darkColor = ComponentLibrary.ColorShift(basicColor, -32);
					htb = new HatchBrush(HatchStyle.SmallCheckerBoard, lightColor, darkColor);
					return htb;

				case GraphElementState.Standart:         // Standardní gradient:
					darkColor = ComponentLibrary.ColorShift(basicColor, -48);
					lightColor = ComponentLibrary.ColorShift(basicColor, 64);
					cbl = new ColorBlend(6);
					cbl.Positions = ComponentLibrary.GetColorBlendPosition(area.Height, new int[] { 0, 1, 5, -6, -2, 0 });
					cbl.Colors = new Color[] { lightColor, lightColor, basicColor, basicColor, darkColor, darkColor };
					lgb.InterpolationColors = cbl;
					return lgb;

				case GraphElementState.SelectedFree:     // Selected, nefixovaný:
					repeatType = GraphicsPaletteBrushRepeatType.None;
					lightColor = ComponentLibrary.ColorShift(basicColor, +96);
					darkColor = ComponentLibrary.ColorShift(basicColor, +16);
					htb = new HatchBrush(HatchStyle.DarkHorizontal, lightColor, darkColor);
					return htb;

				case GraphElementState.ActiveFree:       // Aktivní gradient, nefixovaný:
				case GraphElementState.InEditorFree:     // V editoru, nefixovaný:
					// má opačné pořadí barev (nahoře tmavý, dole světlý), čímž reprezentuje "dolů promáčknutý" stav:
					mediumColor = ComponentLibrary.ColorShift(basicColor, -24);
					basicColor = ComponentLibrary.ColorShift(basicColor, 16, 64, 64);
					darkColor = ComponentLibrary.ColorShift(basicColor, -48);
					lightColor = ComponentLibrary.ColorShift(basicColor, 64, 48, 64);
					cbl = new ColorBlend(8);
					cbl.Positions = ComponentLibrary.GetColorBlendPosition(area.Height, new int[] { 0, 1, 3, 9, -11, -6, -2, 0 });
					cbl.Colors = new Color[] { darkColor, darkColor, mediumColor, basicColor, basicColor, mediumColor, lightColor, lightColor };
					lgb.InterpolationColors = cbl;
					return lgb;

				case GraphElementState.OnMouseFree:       // OnMouse gradient, nefixovaný:
					mediumColor = ComponentLibrary.ColorShift(basicColor, 16, 32, 32);
					darkColor = ComponentLibrary.ColorShift(basicColor, -48);
					lightColor = ComponentLibrary.ColorShift(basicColor, 32, 64, 64);
					cbl = new ColorBlend(6);
					cbl.Positions = ComponentLibrary.GetColorBlendPosition(area.Height, new int[] { 0, 1, 7, -8, -2, 0 });
					cbl.Colors = new Color[] { lightColor, lightColor, mediumColor, mediumColor, darkColor, darkColor };
					lgb.InterpolationColors = cbl;
					return lgb;


				case GraphElementState.Pinned:           // Fixovaný element, připíchnutý špendlíkem k tabuli:
					repeatType = GraphicsPaletteBrushRepeatType.Explicit;
					lightColor = ComponentLibrary.ColorShift(basicColor, +16);
					darkColor = ComponentLibrary.ColorShift(basicColor, -64);
					htb = new HatchBrush(HatchStyle.DiagonalCross, lightColor, darkColor);
					return htb;

				case GraphElementState.SelectedPinned:   // Selected, fixovaný:
					repeatType = GraphicsPaletteBrushRepeatType.Explicit;
					lightColor = ComponentLibrary.ColorShift(basicColor, 64);
					darkColor = ComponentLibrary.ColorShift(basicColor, 16);
					htb = new HatchBrush(HatchStyle.DiagonalCross, lightColor, darkColor);
					return htb;

				case GraphElementState.ActivePinned:     // Aktivní gradient, fixovaný:
				case GraphElementState.InEditorPinned:   // V editoru, fixovaný:
					repeatType = GraphicsPaletteBrushRepeatType.Explicit;
					lightColor = ComponentLibrary.ColorShift(basicColor, -64);
					darkColor = ComponentLibrary.ColorShift(basicColor, 16);
					htb = new HatchBrush(HatchStyle.DiagonalCross, lightColor, darkColor);
					return htb;

				case GraphElementState.OnMousePinned:     // OnMouse gradient, fixovaný:
					repeatType = GraphicsPaletteBrushRepeatType.Explicit;
					lightColor = ComponentLibrary.ColorShift(basicColor, +16);
					darkColor = ComponentLibrary.ColorShift(basicColor, -32);
					htb = new HatchBrush(HatchStyle.DiagonalCross, lightColor, darkColor);
					return htb;

			}
			return new SolidBrush(Color.LightSkyBlue);
		}
		/// <summary>
		/// Vrátí Brush pro graf typu TaskCapacityLink
		/// </summary>
		/// <param name="args"></param>
		/// <param name="area"></param>
		/// <param name="repeatType"></param>
		/// <returns></returns>
		private Brush _GetBrushTaskCapacityLink(GraphElementPaletteArgs args, Rectangle area, out GraphicsPaletteBrushRepeatType repeatType)
		{
			repeatType = GraphicsPaletteBrushRepeatType.Horizontal;
			Color basicColor = args.ElementColor;   // Základní barva, střed objektu
			Color lightColor = basicColor;          // Světlejší barva, většinou bývá nahoře (kromě stavu _GraphElementGradientType.ActiveItemBack)
			Color darkColor = basicColor;           // Tmavší barva, většinou je dole
			Color edgeColor = basicColor;           // Přechodová barva, jen v ActiveItemBack gradientu

			LinearGradientBrush lgb;
			HatchBrush htb;
			switch (args.ElementState)
			{
				case GraphElementState.Dead:             // Neinteraktivní element, nepohyblivý a neselectovatelný:
					repeatType = GraphicsPaletteBrushRepeatType.None;
					basicColor = ComponentLibrary.ColorShift(basicColor, +64);
					darkColor = ComponentLibrary.ColorShift(basicColor, -32);
					htb = new HatchBrush(HatchStyle.SmallCheckerBoard, basicColor, darkColor);
					return htb;


				case GraphElementState.Standart:         // Standardní gradient:
					lightColor = ComponentLibrary.ColorShift(basicColor, 48);
					darkColor = ComponentLibrary.ColorShift(basicColor, -64);
					return new LinearGradientBrush(area, lightColor, darkColor, 90F);

				case GraphElementState.SelectedFree:     // Selected:
					lightColor = ComponentLibrary.ColorShift(basicColor, 32, 96, 32);
					darkColor = ComponentLibrary.ColorShift(basicColor, -32, 0, -32);
					lgb = new LinearGradientBrush(area, lightColor, darkColor, 90F);
					lgb.SetSigmaBellShape(0.667F);
					return lgb;

				case GraphElementState.ActiveFree:       // Aktivní gradient, nefixovaný:
					// má opačné pořadí barev (nahoře tmavý, dole světlý), čímž reprezentuje "dolů promáčknutý" stav:
					darkColor = ComponentLibrary.ColorShift(basicColor, -32);
					lightColor = ComponentLibrary.ColorShift(basicColor, 64);
					return new LinearGradientBrush(area, darkColor, lightColor, 90F);

				case GraphElementState.InEditorFree:
					// má opačné pořadí barev (nahoře tmavý, dole světlý), čímž reprezentuje "dolů promáčknutý" stav:
					darkColor = ComponentLibrary.ColorShift(basicColor, -32);
					lightColor = ComponentLibrary.ColorShift(basicColor, 64);
					return new LinearGradientBrush(area, darkColor, lightColor, 90F);

				case GraphElementState.OnMouseFree:      // OnMouse gradient, nefixovaný:
					lightColor = ComponentLibrary.ColorShift(basicColor, 80);
					darkColor = ComponentLibrary.ColorShift(basicColor, -32, 0, -32);
					return new LinearGradientBrush(area, lightColor, darkColor, 90F);


				case GraphElementState.Pinned:           // Fixovaný element, připíchnutý špendlíkem k tabuli:
					repeatType = GraphicsPaletteBrushRepeatType.None;
					lightColor = ComponentLibrary.ColorShift(basicColor, +16);
					darkColor = ComponentLibrary.ColorShift(basicColor, -64);
					htb = new HatchBrush(HatchStyle.DiagonalCross, lightColor, darkColor);
					return htb;

				case GraphElementState.SelectedPinned:   // Selected, Fixovaný element, připíchnutý špendlíkem k tabuli:
					repeatType = GraphicsPaletteBrushRepeatType.None;
					lightColor = ComponentLibrary.ColorShift(basicColor, +64);
					darkColor = ComponentLibrary.ColorShift(basicColor, 0);
					htb = new HatchBrush(HatchStyle.DiagonalCross, lightColor, darkColor);
					return htb;

				case GraphElementState.ActivePinned:     // Aktivní gradient, fixovaný:
				case GraphElementState.InEditorPinned:   // V editoru, fixovaný:
					repeatType = GraphicsPaletteBrushRepeatType.Explicit;
					lightColor = ComponentLibrary.ColorShift(basicColor, -64);
					darkColor = ComponentLibrary.ColorShift(basicColor, 16);
					htb = new HatchBrush(HatchStyle.DiagonalCross, lightColor, darkColor);
					return htb;

				case GraphElementState.OnMousePinned:     // OnMouse gradient, fixovaný:
					repeatType = GraphicsPaletteBrushRepeatType.Explicit;
					lightColor = ComponentLibrary.ColorShift(basicColor, +16);
					darkColor = ComponentLibrary.ColorShift(basicColor, -32);
					htb = new HatchBrush(HatchStyle.DiagonalCross, lightColor, darkColor);
					return htb;
			}
			return new SolidBrush(Color.LightSkyBlue);
		}
		/// <summary>
		/// Vrátí font pro danou příležitost
		/// </summary>
		/// <param name="args"></param>
		/// <returns></returns>
		public Font GetFont(GraphElementPaletteArgs args)
		{
			return new Font(SystemFonts.DefaultFont, FontStyle.Regular);
		}
		/// <summary>
		/// Vrátí obrázek pro danou příležitost
		/// </summary>
		/// <param name="args"></param>
		/// <returns></returns>
		public Image GetImage(GraphElementPaletteArgs args)
		{
			return null;
		}
	}
	#endregion
}
